﻿using System;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;
using HeritageAcademy.Documentation;
using HeritageAcademy.Models.DataModels;
using HeritageAcademy.Models.ViewModels;
using HeritageAcademy.Shared;

namespace HeritageAcademy.Window
{
	/// <summary>
	/// Window content class.
	/// </summary>
	public partial class WindowContent
	{
        #region Parameters
        
        private FrameworkElement _currentView;
        private readonly UsersDataHandler _usersDataHandler;
	    private readonly SettingsConfigViewModel _settingsDataHandler;
        private User _currentUser;
        private readonly LibraryViewModel _library;
        
        #endregion

        #region Ctor
        
        public WindowContent()
		{
            InitializeComponent();

            _currentUser = new User();
            
            // Initilize data view models
            _settingsDataHandler = new SettingsConfigViewModel();
            _usersDataHandler = new UsersDataHandler();

            // library init & loading
            _library = new LibraryViewModel();
            Navigator.ShowLibrary(_library);

            // Window loaded handler
            Loaded += WindowContent_Loaded;
		}      
	    
        #endregion

        #region Handlers

        #region Load window
        /// <summary>
        /// Window loaded event handler.
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Routed event arguments</param>
        void WindowContent_Loaded(object sender, RoutedEventArgs e)
        {
            // For live preview purposes in Blend, show the main workflow and not the login sequence...
            var assembly = Assembly.GetEntryAssembly();
            if (!assembly.FullName.Contains("Blend"))
                LoadCore();
        }

	    /// <summary>
        /// Load core event handlers and values.
        /// </summary>
        private void LoadCore()
        {
            // Prepare system
            RegisterFileAssociation();

            // Assign handlers
            grdLoggedUser.MouseLeftButtonDown += logout_MouseButtonEventHandler;
            Registration.RegistrationButtonEventHandler = btnRegister_Click;
            btnStartWellcome.Click += btnStartWellcome_Click;

            // fill quotation scroller
            quotes.Clear();
            quotes.Add("Жизнь несправедлива – свыкнись с этим фактом.");
            quotes.Add("Миру наплевать на твое самоощущение и самоуважение. Мир ожидает от тебя каких-нибудь достижений перед тем как принять во внимание твое чувство собственного достоинства.");
            quotes.Add("Очень маловероятно что тебе начнуть платить 40 тысяч в год сразу после окончания школы. Ты не станешь вице-президентом компании, с лимузином и личным шофером, пока ты не заслужишь этого.");
            quotes.Add("Если ты думаешь, что твой учитель строг и требователен - подожди знакомства со своим боссом. В отличие от учителя, карьера босса зависит от того как ты справляешься со своими заданиями.");
            quotes.Add("Обжаривать бургеры в Макдональдсе – не ниже твоего достоинства. Твои прадеды назвали бы любую – даже такую – работу «хорошим шансом».");
            quotes.Add("Hе спеши обвинять в каждой своей неудаче своих родителей. Hе ной и не носись со своими неудачами, учись на них.");
            quotes.Add("До твоего рождения твои родители не были такими скучными и неинтересными людьми, какими они кажутся тебе сейчас. Они стали такими, зарабатывая на твое беззаботное детство, стирая твою одежду и слушая твою бесконечную болтовню о том какой ты классный. Поэтому перед тем как отправляться спасать леса Амазонки от уничтожения жадным поколением твоих родителей, попытайся для начала привести в порядок свою комнату.");
            quotes.Add("Твоя школа отменила деление на победителей и лузеров, жизнь - нет. В некоторых школах прекратили ставить плохие отметки, разрешили сколько угодно попыток сдать тест или ответить на вопрос... Это не имеет ни малейшего подобия ни к чему происходящему в жизни.");
            quotes.Add("Жизнь не разделена на семестры, летних каникул в ней не существует, и очень мало работодателей заинтересованы в помощи тебе найти твое собственное «я». Тебе придется делать это в твое личное время.");
            quotes.Add("Hе путай реальную жизнь с тем, что показывают по телевидению. В жизни людям приходится большую часть времени проводить не в кофейне, а на рабочем месте.");
            quotes.Add("Поддерживай хорошие отношения с «очкариками-ботаниками». Скорее всего, один из них когда-то станет твоим начальником.");
            quotes.StartAutoScrolling(14);

            // Set user list       
            _usersDataHandler.SetUsersList(Users.Children, password_KeyUp, IOHelper.CommonMetaDataFolder);

            // Set current view content
            _currentView = loginContent;
        }

        private static void RegisterFileAssociation()
        {
            var path = Assembly.GetEntryAssembly().Location;
            string appId = Path.GetFileNameWithoutExtension(path).Replace(" ", "_");
            FileAssociationHelper.Register(
              appId,
              appId,
              string.Format("\"{0}\" \"%1\"", path),
              Shared.Properties.Resources.Course_PackageExtension);
        }
        #endregion

        #region Welcome

	    void btnStartWellcome_Click(object sender, RoutedEventArgs e)
        {
            WelcomeTour.Show();
        }
        #endregion

        #region Registration
        /// <summary>
        /// Register new user button click event handler.
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Routed event arguments</param>
        void btnRegister_Click(object sender, RoutedEventArgs e)
        {
            // Register new user
            if (_usersDataHandler.RegisterNewUser(Registration.NewUser()))
            {
                // TODO: move string to resource
                Message.Show("Зарегистрирован новый пользователь", Shared.Message.Type.Info, true);
                // Set and show updated user list
                _usersDataHandler.SetUsersList(Users.Children, password_KeyUp, IOHelper.CommonMetaDataFolder);
                //_usersDataHandler.SetUsersList(crsUsersCarousel.Items, password_KeyUp);
                Registration.Clear();
            }
            else
                // TODO: move string to resource
                Message.Show("Reg001 - Не удалось зарегистрировать нового пользователя", Shared.Message.Type.Error);
        }
        #endregion

        #region Logout
        /// <summary>
        /// Logout button click event handler.
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Mouse button event arguments</param>
        void logout_MouseButtonEventHandler(object sender, MouseButtonEventArgs e)
        {
            // Set all users flag "Active" to False.
            // TODO: Implement (or NOT?) dialog "Do you want to save changes before exit?"
            _usersDataHandler.UnSetCurrentUser();
            // Return Navigator to LibraryView 
            // (to force user make choice of book and initiate settings reinitialization)
            // TODO: make this not so tricky
            Navigator.ComeBackToLibrary();

            var fadeOut = FindResource("fadeOut") as Storyboard;
            if (fadeOut != null)
            {
                fadeOut = fadeOut.Clone();
                fadeOut.Completed += fadeOut_Completed;
                fadeOut.Begin(_currentView);
            }
            else
            {
                if (Message != null) Message.Show("res002 - ресурс не найден", Shared.Message.Type.Error, true);
            }
        }

        /// <summary>
        /// Show login screen animation handler.
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event arguments</param>
        void fadeOut_Completed(object sender, EventArgs e)
        {
            var fadeOut = FindResource("fadeOut") as Storyboard;
            if (fadeOut != null)
            {
                fadeOut = fadeOut.Clone();
                fadeOut.Completed -= fadeOut_Completed;
            }
            else
            {
                if (Message != null) Message.Show("res002 - ресурс не найден", Shared.Message.Type.Error, true);
            }    


            var fadeIn = FindResource("fadeIn") as Storyboard;
            if (fadeIn != null)
            {
                fadeIn.Begin(loginContent);
            }
            else
            {
                if (Message != null) Message.Show("res001 - ресурс не найден", Shared.Message.Type.Error, true);
            }

            _usersDataHandler.UserTile.Margin = new Thickness(0, 5, 0, 20);
            _usersDataHandler.UserTile.PasswordBorder.Visibility = Visibility.Hidden;
            _usersDataHandler.UserTile.PasswordInput.Password = string.Empty;
        }
        #endregion

        #region Login
        /// <summary>
        /// Password click event handler.
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Key event arguments</param>
        void password_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Enter) return;
            
            if (((PasswordBox)sender).Password == _usersDataHandler.UserTile.Password)
            {
                // Initialize current user object
                _currentUser = _usersDataHandler.SetCurrentUser();
                tbUserNick.Text = _currentUser.Login;
                grdLoggedUser.Visibility = Visibility.Visible;

                _settingsDataHandler.InitializeSettings(_currentUser.Id);
                //if (!_settingsDataHandler.LastSelectedViewIsLibrary)
                //Navigator.ShowLibrary();

                // Hide user list
                var fadeOutUser = FindResource("fadeOut") as Storyboard;
                if (fadeOutUser != null)
                {
                    fadeOutUser.Begin(loginContent);
                }
                else
                {
                    if (Message != null) Message.Show("res002 - ресурс не найден", Shared.Message.Type.Error, true);
                }

                // Slide up current user card
                var fadeIn = FindResource("fadeIn") as Storyboard;
                if (fadeIn != null)
                {
                    fadeIn = fadeIn.Clone();
                    fadeIn.Completed += loggedUserTile_fadeIn_Completed;
                    fadeIn.Begin(grdLoggedUser);
                }
                else
                {
                    if (Message != null) Message.Show("res001 - ресурс не найден", Shared.Message.Type.Error, true);
                }
            }
            else
            {
                // Move string to resource
                Message.Show("Вы ввели неверный пароль!", Shared.Message.Type.Warrning, true);
                (sender as PasswordBox).Password = string.Empty;
            }
        }

	    /// <summary>
        /// User logged in event handler: change currentView to default value (menuContent),
        /// show main content and menu.
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event arguments</param>
        void loggedUserTile_fadeIn_Completed(object sender, EventArgs e)
        {
            // Unassine handler
            var slideUp = FindResource("fadeIn") as Storyboard;
            if (slideUp != null)
            {
                slideUp = slideUp.Clone();
                slideUp.Completed -= loggedUserTile_fadeIn_Completed;
            }           
            else
            {
                if (Message != null) Message.Show("res001 - ресурс не найден", Shared.Message.Type.Error, true);
            }

            // Return data to default position
            if (_currentView != mainContent)
                ChangeView(mainContent);
                      
            // Show main content and menu
            var fadeIn = FindResource("fadeIn") as Storyboard;
            if (fadeIn != null)
            {
                fadeIn.Begin(_currentView);
            }
            else
            {
                if (Message != null) Message.Show("res001 - ресурс не найден", Shared.Message.Type.Error, true);
            }
        }
        #endregion

        #region Library Navigation
        /*
        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            if (e.Key == Key.Space ||
                e.Key == Key.Down ||
                e.Key == Key.Right ||
                e.Key == Key.Enter ||
                e.Key == Key.Return ||
                e.Key == Key.BrowserForward ||
                e.Key == Key.PageDown)
            {
                if (this.Navigator.Current.IsBookVisible)
                {
                    this.Navigator.Current.Book.BookViewer.NextPage();
                }
            }

            else if (e.Key == Key.Back ||
                e.Key == Key.Up ||
                e.Key == Key.Left ||
                e.Key == Key.PageUp ||
                e.Key == Key.BrowserBack)
            {
                if (Navigator.Current.IsBookVisible)
                {
                    Navigator.Current.Book.BookViewer.PreviousPage();
                }
            }

            base.OnPreviewKeyDown(e);
        }
        */
        #endregion

        #endregion

        #region Change View
        /// <summary>
        /// Change current view.
        /// </summary>
        /// <param name="newView">New view (framework element)</param>
        public void ChangeView(FrameworkElement newView)
        {
            var fadeOutContent = FindResource("fadeOut") as Storyboard;
            if (fadeOutContent != null)
            {
                fadeOutContent = fadeOutContent.Clone();
                fadeOutContent.Completed += fadeOutContent_Completed;
                fadeOutContent.Begin(_currentView);
            }
            
            _currentView = newView;
        }

        /// <summary>
        /// Fade out content completed event handler.
        /// Start new view fade in when the old view fade out ends.
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event arguments</param>
        void fadeOutContent_Completed(object sender, EventArgs e)
        {
            var fadeOutContent = FindResource("fadeOut") as Storyboard;
            if (fadeOutContent != null)
            {
                fadeOutContent = fadeOutContent.Clone();
                fadeOutContent.Completed -= fadeOutContent_Completed;
            }

            var fadeInContent = FindResource("fadeIn") as Storyboard;
            if (fadeInContent != null) fadeInContent.Begin(_currentView);
        }      
        #endregion  
    }
}